#include "wx/wxprec.h"

#if wxUSE_DIRDLG && defined( __WXGTK24__ )

#include "wx/dirdlg.h"
#include "wx/gtk/private.h"
#include <unistd.h>

extern "C" {
  static void gtk_dirdialog_ok_callback( GtkWidget *widget, wxDirDialog *dialog ) {
    if( dialog->HasFlag( wxDD_CHANGE_DIR ) ) {
      wxGtkString filename( gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( widget ) ) );
      chdir( filename );
    }
    wxCommandEvent event( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK );
    event.SetEventObject( dialog );
    dialog->GetEventHandler()->ProcessEvent( event );
  }
}

extern "C" {
  static void gtk_dirdialog_cancel_callback( GtkWidget *( w ),
      wxDirDialog *dialog ) {
    wxCommandEvent event( wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL );
    event.SetEventObject( dialog );
    dialog->GetEventHandler()->ProcessEvent( event );
  }
}

extern "C" {
  static void gtk_dirdialog_response_callback( GtkWidget *w,
      gint response,
      wxDirDialog *dialog ) {
    wxapp_install_idle_handler();
    if( response == GTK_RESPONSE_ACCEPT ) {
      gtk_dirdialog_ok_callback( w, dialog );
    } else {
      gtk_dirdialog_cancel_callback( w, dialog ); // GTK_RESPONSE_CANCEL or GTK_RESPONSE_NONE
    }
  }
}

IMPLEMENT_DYNAMIC_CLASS( wxDirDialog, wxGenericDirDialog )

BEGIN_EVENT_TABLE( wxDirDialog, wxGenericDirDialog )
  EVT_BUTTON( wxID_OK, wxDirDialog::OnFakeOk )
END_EVENT_TABLE()

wxDirDialog::wxDirDialog( wxWindow* parent, const wxString& title, const wxString& defaultPath, long style,
                          const wxPoint& pos, const wxSize& sz, const wxString& name ) {
  if( !gtk_check_version( 2, 4, 0 ) ) {
    m_message = title;
    m_needParent = false;
    if( !PreCreation( parent, pos, wxDefaultSize ) || !CreateBase( parent, wxID_ANY, pos, wxDefaultSize, style,
        wxDefaultValidator, wxT( "dirdialog" ) ) ) {
      wxFAIL_MSG( wxT( "wxDirDialog creation failed" ) );
      return;
    }
    GtkWindow* gtk_parent = NULL;
    if( parent ) {
      gtk_parent = GTK_WINDOW( gtk_widget_get_toplevel( parent->m_widget ) );
    }
    m_widget = gtk_file_chooser_dialog_new( wxGTK_CONV( m_message ), gtk_parent, GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL );
    gtk_dialog_set_default_response( GTK_DIALOG( m_widget ), GTK_RESPONSE_ACCEPT );
    g_signal_connect( G_OBJECT( m_widget ), "delete_event", G_CALLBACK( gtk_widget_hide_on_delete ), ( gpointer )this );
    g_signal_connect( m_widget, "response", G_CALLBACK( gtk_dirdialog_response_callback ), this );
    if( !defaultPath.empty() ) {
      gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( m_widget ), defaultPath.utf8_str() );
    }
  } else {
    wxGenericDirDialog::Create( parent, title, defaultPath, style, pos, sz, name );
  }
}

void wxDirDialog::OnFakeOk( wxCommandEvent &event ) {
  if( !gtk_check_version( 2, 4, 0 ) ) {
    EndDialog( wxID_OK );
  } else {
    wxGenericDirDialog::OnOK( event );
  }
}

int wxDirDialog::ShowModal() {
  if( !gtk_check_version( 2, 4, 0 ) ) {
    return wxDialog::ShowModal();
  } else {
    return wxGenericDirDialog::ShowModal();
  }
}

bool wxDirDialog::Show( bool show ) {
  if( !gtk_check_version( 2, 4, 0 ) ) {
    return wxDialog::Show( show );
  } else {
    return wxGenericDirDialog::Show( show );
  }
}

void wxDirDialog::DoSetSize( int x, int y, int width, int height, int sizeFlags ) {
  if( !m_wxwindow ) {
    return;
  } else {
    wxGenericDirDialog::DoSetSize( x, y, width, height, sizeFlags );
  }
}

void wxDirDialog::SetPath( const wxString& dir ) {
  if( !gtk_check_version( 2, 4, 0 ) ) {
    if( wxDirExists( dir ) ) {
      gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER( m_widget ), dir.utf8_str() );
    }
  } else {
    wxGenericDirDialog::SetPath( dir );
  }
}

wxString wxDirDialog::GetPath() const {
  if( !gtk_check_version( 2, 4, 0 ) ) {
    wxGtkString str( gtk_file_chooser_get_filename( GTK_FILE_CHOOSER( m_widget ) ) );
    return wxString::FromUTF8( str );
  }
  return wxGenericDirDialog::GetPath();
}

#endif
